package io.kimmking.dubbo.demo.provider.service.impl;

import io.kimmking.dubbo.demo.api.exception.DemoError;
import io.kimmking.dubbo.demo.api.exception.DemoException;
import io.kimmking.dubbo.demo.provider.mapper.DollarAccountMapper;
import io.kimmking.dubbo.demo.provider.mapper.RmbAccountMapper;
import io.kimmking.dubbo.demo.provider.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;

/**
 * @author gechenpeng
 * @date 2021-06-07
 */
@Service
public class AccountServiceImpl implements AccountService {

    private final RmbAccountMapper rmbAccountMapper;

    private final DollarAccountMapper dollarAccountMapper;

    @Autowired(required = false)
    public AccountServiceImpl(RmbAccountMapper rmbAccountMapper, DollarAccountMapper dollarAccountMapper) {
        this.rmbAccountMapper = rmbAccountMapper;
        this.dollarAccountMapper = dollarAccountMapper;
    }

    @Override
    public void freezeRmbAmount(String userId, BigDecimal amount) {
        int row = rmbAccountMapper.freezeAmount(userId, amount);
        if (row != 1) {
            throw new DemoException(DemoError.BUSINESS_ERROR);
        }
    }

    @Override
    public void unfreezeRmbAmount(String userId, BigDecimal amount) {
        int row = rmbAccountMapper.unfreezeAmount(userId, amount);
        if (row != 1) {
            throw new DemoException(DemoError.BUSINESS_ERROR);
        }
    }

    @Override
    @Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class)
    public void doExchangeForDollar(String userId, BigDecimal rmbAmount) {
        int row = rmbAccountMapper.deductFromFrozen(userId, rmbAmount);
        if (row != 1) {
            throw new DemoException(DemoError.BUSINESS_ERROR);
        }

        dollarAccountMapper.increaseAmount(userId, rmbAmount.divide(BigDecimal.valueOf(7)));
    }
}
